package cn.xval.ft.core.marketdata.manage;

import cn.xval.ft.common.Helper;
import cn.xval.ft.core.ctp.*;
import cn.xval.ft.core.marketdata.exceptions.MdApiException;
import cn.xval.ft.core.marketdata.manage.method.Login;
import cn.xval.ft.core.marketdata.manage.method.Subscriber;
import cn.xval.ft.grpc.CollectInfo;
import cn.xval.utils.crypto.MD5;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

@Slf4j
public class MarketDataSpi extends CThostFtdcMdSpi implements Runnable {
    @Getter
    private final CollectInfo info;

    @Getter
    private final CThostFtdcMdApi connect;

    @Getter
    private final List<StatusInfo> history = new ArrayList<>();

    @Getter
    private StatusInfo status;
    @Getter
    private String tradingDay;

    public StatusInfo setCurrentStatus(SpiStatus status) {
        StatusInfo si = new StatusInfo();
        si.setStatus(status);
        history.add(si);
        this.status = si;
        return si;
    }

    public String getId() {
        return Helper.generateMarketConnectionId(info.getUserId(), info.getBrokerId(), info.getHost());
    }

    public MarketDataSpi(CollectInfo info) {
        super();
        setCurrentStatus(SpiStatus.ready);
        this.info = info;
        this.connect = CThostFtdcMdApi.CreateFtdcMdApi();
    }

    public void start() throws MdApiException {
        if (connect == null) {
            throw new MdApiException("创建 行情 连接对象失败");
        }
        connect.RegisterSpi(this);
        if (info.getFrontResolveType() == 0)
            connect.RegisterFront(info.getHost());
        else
            connect.RegisterNameServer(info.getHost());
        setCurrentStatus(SpiStatus.connecting);
        connect.Init();
    }
    public void disconnect() {}

    @Override
    public void run() {

    }

    private final Login login = new Login(this);
    /**
     * 建立连接后，进行登陆操作
     */
    @Override
    public void OnFrontConnected() {
        // 登录操作
        login.doLogin();
    }

    @Override
    public void OnRspUserLogin(CThostFtdcRspUserLoginField pRspUserLogin, CThostFtdcRspInfoField pRspInfo, int nRequestID, boolean bIsLast) {
        if (login.onRspUserLogin(pRspUserLogin, pRspInfo, nRequestID, bIsLast)) {
            // 登录成功
            this.tradingDay = pRspUserLogin.getTradingDay();
        }
    }

    private final Subscriber subscriber = new Subscriber(this);
    public void subscribe(List<String> contractCodes) {
        subscriber.doSubscribe(contractCodes);
    }
    @Override
    public void OnRspSubMarketData(CThostFtdcSpecificInstrumentField pSpecificInstrument, CThostFtdcRspInfoField pRspInfo, int nRequestID, boolean bIsLast) {
        subscriber.onRspSubMarketData(pSpecificInstrument, pRspInfo, nRequestID, bIsLast);
    }
    @Override
    public void OnRtnDepthMarketData(CThostFtdcDepthMarketDataField pDepthMarketData) {
        subscriber.onRtnDepthMarketData(pDepthMarketData);
    }
}
